﻿using HBKY.Shop.IRepository.MongoRepository;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using SqlSugar;

namespace HBKY.Shop.Repository.MongoRepository
{
    public class MongoRepository<TEntity> : IMongoRepository<TEntity> where TEntity : class, new()
    {
        private readonly MongoDbContext _context;
        private IMongoCollection<TEntity> _collection;
        public IMongoQueryable<TEntity> Queryable { get { return _collection.AsQueryable<TEntity>(); } }
        public IMongoCollection<TEntity> Collection { get { return _collection; } }

        public MongoRepository()
        {
            _context = new MongoDbContext();
            if (typeof(TEntity).GetTypeInfo().GetCustomAttributes(typeof(SqlSugar.SugarTable), true)
                           .FirstOrDefault((x => x.GetType() == typeof(SugarTable))) is SugarTable sugarTable &&
                       !string.IsNullOrEmpty(sugarTable.TableName))
            {
                _collection = _context.Db.GetCollection<TEntity>(sugarTable.TableName);
            }
            else
            {
                _collection = _context.Db.GetCollection<TEntity>(typeof(TEntity).Name.ToLower());
            }
        }

        public async Task AddAsync(TEntity entity)
        {
            await _collection.InsertOneAsync(entity);
        }

        /// <summary>
        ///批量添加 
        /// </summary>
        public async Task AddAsync(List<TEntity> entitys)
        {
            await _collection.InsertManyAsync(entitys);
        }

        public async Task<TEntity> GetAsync(int Id)
        {
            var filter = Builders<TEntity>.Filter.Eq("Id", Id);
            return await _collection.Find(filter).SortBy(o => o).FirstOrDefaultAsync();
        }

        public async Task<List<TEntity>> GetListAsync()
        {
            return await _collection.Find(new BsonDocument()).ToListAsync();
        }

        public async Task InsertOne(TEntity model)
        {
            await _collection.InsertOneAsync(model);
        }

        public async Task InsertMany(params TEntity[] modes)
        {
            await _collection.InsertManyAsync(modes);
        }

        public IMongoQueryable<TEntity> Select(int pageIndex, int pageSize)
        {
            return Queryable.Skip(pageSize * (pageIndex - 1)).Take(pageSize);
        }
        public IMongoQueryable<TEntity> Select(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, object>> keySelector, int pageIndex, int pageSize)
        {
            return Queryable.Where(predicate).OrderBy(keySelector).Skip(pageSize * (pageIndex - 1)).Take(pageSize);
        }

        public async Task UpdateMany(Expression<Func<TEntity, bool>> filter, UpdateDefinition<TEntity> update)
        {
            await _collection.UpdateManyAsync(filter, update);
        }

        public async Task UpdateOne(Expression<Func<TEntity, bool>> filter, TEntity update)
        {
            await _collection.ReplaceOneAsync(filter, update);
        }

        /// <summary>
        /// 删除
        /// </summary>
        public async Task DeleteManyAsync(Expression<Func<TEntity, bool>> filter)
        {
            await _collection.DeleteManyAsync(filter);
        }

        public Expression<Func<TEntity, TProperty>> ConvertToPropertyExpression<TProperty>(string propertyName)
        {
            var lambdaParam = Expression.Parameter(typeof(TEntity));
            var lambdaBody = Expression.Property(lambdaParam, propertyName);
            return Expression.Lambda<Func<TEntity, TProperty>>(lambdaBody, lambdaParam);
        }
    }
}
